/**
 * 菜单结构验证器
 * 确保生成的HTML菜单严格符合 generate-menu.md 中的规范
 */

export interface MenuValidationResult {
  isValid: boolean
  errors: string[]
  warnings: string[]
  suggestions: string[]
}

export interface MenuStructure {
  title: string
  icon?: string
  path?: string
  children?: MenuStructure[]
}

export class MenuValidator {
  
  /**
   * 验证HTML菜单结构是否符合规范
   */
  static validateMenuHTML(html: string): MenuValidationResult {
    const result: MenuValidationResult = {
      isValid: true,
      errors: [],
      warnings: [],
      suggestions: []
    }

    // 检查基本结构
    this.checkBasicStructure(html, result)
    
    // 检查CSS类名
    this.checkCSSClasses(html, result)
    
    // 检查图标格式
    this.checkIconFormat(html, result)
    
    // 检查路径格式
    this.checkPathFormat(html, result)
    
    // 检查嵌套结构
    this.checkNestingStructure(html, result)

    result.isValid = result.errors.length === 0

    return result
  }

  /**
   * 从PRD内容中提取菜单结构
   */
  static extractMenuFromPRD(prdContent: string): MenuStructure[] {
    const menuSection = this.findMenuSection(prdContent)
    if (!menuSection) {
      return []
    }

    return this.parseMenuStructure(menuSection)
  }

  /**
   * 生成符合规范的菜单HTML
   */
  static generateMenuHTML(menuData: MenuStructure[]): string {
    let html = '<nav class="funi-menu">\n'
    
    for (const item of menuData) {
      if (item.children && item.children.length > 0) {
        // 有子菜单的一级菜单
        html += this.generateMenuGroup(item)
      } else {
        // 无子菜单的一级菜单
        html += this.generateMenuItem(item)
      }
    }
    
    html += '</nav>'
    return html
  }

  private static checkBasicStructure(html: string, result: MenuValidationResult): void {
    // 检查是否包含 funi-menu 导航容器
    if (!html.includes('class="funi-menu"')) {
      result.errors.push('缺少 <nav class="funi-menu"> 容器')
    }

    // 检查是否包含菜单列表
    if (!html.includes('class="funi-menu-list"')) {
      result.errors.push('缺少 <ul class="funi-menu-list"> 菜单列表')
    }

    // 检查是否包含菜单项
    if (!html.includes('class="funi-menu-item"')) {
      result.errors.push('缺少 <li class="funi-menu-item"> 菜单项')
    }
  }

  private static checkCSSClasses(html: string, result: MenuValidationResult): void {
    const requiredClasses = [
      'funi-menu',
      'funi-menu-list',
      'funi-menu-item',
      'funi-menu-link',
      'funi-menu-text'
    ]

    for (const className of requiredClasses) {
      if (!html.includes(`class="${className}"`)) {
        result.errors.push(`缺少必需的CSS类: ${className}`)
      }
    }

    // 检查菜单组相关类名
    if (html.includes('children') || html.includes('子菜单')) {
      const groupClasses = ['funi-menu-group', 'funi-menu-group-title', 'funi-menu-group-toggle']
      for (const className of groupClasses) {
        if (!html.includes(`class="${className}"`)) {
          result.warnings.push(`可能缺少菜单组CSS类: ${className}`)
        }
      }
    }
  }

  private static checkIconFormat(html: string, result: MenuValidationResult): void {
    // 检查图标格式
    const iconPattern = /<iconify-icon\s+icon="[^"]+"\s+class="funi-menu-icon"><\/iconify-icon>/g
    const iconMatches = html.match(iconPattern)
    
    if (!iconMatches) {
      result.warnings.push('未找到符合规范的图标格式，应使用 <iconify-icon icon="mdi:xxx" class="funi-menu-icon"></iconify-icon>')
    }

    // 检查是否使用了错误的图标格式
    if (html.includes('<i class=') || html.includes('<span class="icon')) {
      result.errors.push('使用了错误的图标格式，应使用 iconify-icon 标签')
    }
  }

  private static checkPathFormat(html: string, result: MenuValidationResult): void {
    // 检查路径格式
    const hrefPattern = /href="([^"]+)"/g
    const matches = html.matchAll(hrefPattern)
    
    for (const match of matches) {
      const path = match[1]
      if (!path.startsWith('#/') && !path.startsWith('/')) {
        result.warnings.push(`路径格式可能不正确: ${path}，建议使用hash路由格式 #/path`)
      }
    }
  }

  private static checkNestingStructure(html: string, result: MenuValidationResult): void {
    // 检查嵌套结构
    if (html.includes('funi-menu-group')) {
      // 检查菜单组结构
      if (!html.includes('funi-menu-group-title')) {
        result.errors.push('菜单组缺少 funi-menu-group-title')
      }
      
      if (!html.includes('funi-menu-group-toggle')) {
        result.warnings.push('菜单组缺少展开/折叠图标 funi-menu-group-toggle')
      }
    }
  }

  private static findMenuSection(prdContent: string): string | null {
    // 查找菜单结构部分 - 移除对特定部分编号的限制
    const patterns = [
      // 匹配任意部分的系统功能菜单结构
      /第[一二三四五六七八九十\d]+部分[：:]\s*系统功能菜单结构([\s\S]*?)(?=第[一二三四五六七八九十\d]+部分|$)/i,
      // 直接匹配系统功能菜单结构标题
      /系统功能菜单结构[：:]?([\s\S]*?)(?=第[一二三四五六七八九十\d]+部分|$)/i,
      // 匹配简化的菜单结构标题
      /菜单结构[：:]?([\s\S]*?)(?=第[一二三四五六七八九十\d]+部分|$)/i,
      // 匹配功能菜单标题
      /功能菜单[：:]?([\s\S]*?)(?=第[一二三四五六七八九十\d]+部分|$)/i
    ]

    for (const pattern of patterns) {
      const match = prdContent.match(pattern)
      if (match) {
        // 返回捕获组内容，如果没有捕获组则返回整个匹配
        return match[1] ? match[1].trim() : match[0].trim()
      }
    }

    return null
  }

  private static parseMenuStructure(menuSection: string): MenuStructure[] {
    const lines = menuSection.split('\n').filter(line => line.trim())
    const menuItems: MenuStructure[] = []
    let currentParent: MenuStructure | null = null

    for (const line of lines) {
      const trimmed = line.trim()
      
      // 跳过标题行和空行
      if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith('第')) {
        continue
      }

      // 检查缩进级别
      const indent = line.length - line.trimStart().length
      
      if (trimmed.startsWith('-') || trimmed.startsWith('*')) {
        const title = trimmed.substring(1).trim()
        
        if (indent <= 2) {
          // 一级菜单
          const menuItem: MenuStructure = {
            title,
            icon: this.generateIcon(title),
            children: []
          }
          
          // 如果没有子菜单，添加路径
          if (!this.hasChildren(lines, lines.indexOf(line))) {
            menuItem.path = this.generatePath(title)
            delete menuItem.children
          }
          
          menuItems.push(menuItem)
          currentParent = menuItem
        } else {
          // 二级菜单
          if (currentParent && currentParent.children) {
            currentParent.children.push({
              title,
              path: this.generatePath(title, currentParent.title)
            })
          }
        }
      }
    }

    return menuItems
  }

  private static hasChildren(lines: string[], currentIndex: number): boolean {
    if (currentIndex >= lines.length - 1) return false
    
    const currentIndent = lines[currentIndex].length - lines[currentIndex].trimStart().length
    const nextLine = lines[currentIndex + 1]
    const nextIndent = nextLine.length - nextLine.trimStart().length
    
    return nextIndent > currentIndent && (nextLine.trim().startsWith('-') || nextLine.trim().startsWith('*'))
  }

  private static generateIcon(title: string): string {
    const iconMap: Record<string, string> = {
      '工作台': 'mdi:view-dashboard',
      '仪表板': 'mdi:view-dashboard',
      '首页': 'mdi:home',
      '用户管理': 'mdi:account-group',
      '用户': 'mdi:account',
      '角色管理': 'mdi:account-key',
      '权限管理': 'mdi:shield-account',
      '系统设置': 'mdi:cog',
      '设置': 'mdi:cog',
      '采购': 'mdi:cart',
      '订单': 'mdi:file-document',
      '项目': 'mdi:folder-open',
      '文档': 'mdi:file-document-outline',
      '报表': 'mdi:chart-line',
      '统计': 'mdi:chart-bar',
      '日志': 'mdi:text-box',
      '监控': 'mdi:monitor',
      '通知': 'mdi:bell',
      '消息': 'mdi:message'
    }

    for (const [keyword, icon] of Object.entries(iconMap)) {
      if (title.includes(keyword)) {
        return icon
      }
    }

    return 'mdi:circle-medium' // 默认图标
  }

  private static generatePath(title: string, parentTitle?: string): string {
    const pathMap: Record<string, string> = {
      '工作台': '/dashboard',
      '仪表板': '/dashboard',
      '首页': '/home',
      '用户管理': '/user-management',
      '角色管理': '/role-management',
      '权限管理': '/permission-management',
      '系统设置': '/system-settings'
    }

    if (pathMap[title]) {
      return pathMap[title]
    }

    // 生成基于标题的路径
    let path = title
      .replace(/[^\u4e00-\u9fa5a-zA-Z0-9]/g, '-')
      .replace(/-+/g, '-')
      .replace(/^-|-$/g, '')
      .toLowerCase()

    if (parentTitle) {
      const parentPath = this.generatePath(parentTitle).replace('/', '')
      path = `/${parentPath}/${path}`
    } else {
      path = `/${path}`
    }

    return path
  }

  private static generateMenuItem(item: MenuStructure): string {
    return `  <ul class="funi-menu-list">
    <li class="funi-menu-item">
      <a href="${item.path}" class="funi-menu-link">
        <iconify-icon icon="${item.icon}" class="funi-menu-icon"></iconify-icon>
        <span class="funi-menu-text">${item.title}</span>
      </a>
    </li>
  </ul>
`
  }

  private static generateMenuGroup(item: MenuStructure): string {
    const groupId = item.title.replace(/[^\u4e00-\u9fa5a-zA-Z0-9]/g, '-').toLowerCase()
    
    let html = `  <div class="funi-menu-group" data-group-id="${groupId}">
    <div class="funi-menu-group-title">
      <div style="display: flex; align-items: center;">
        <iconify-icon icon="${item.icon}" class="funi-menu-icon"></iconify-icon>
        <span>${item.title}</span>
      </div>
      <svg class="funi-menu-group-toggle" width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
        <path d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z" />
      </svg>
    </div>
    <ul class="funi-menu-list">
`

    if (item.children) {
      for (const child of item.children) {
        html += `      <li class="funi-menu-item">
        <a href="${child.path}" class="funi-menu-link">
          <span class="funi-menu-text">${child.title}</span>
        </a>
      </li>
`
      }
    }

    html += `    </ul>
  </div>
`

    return html
  }
}
